Ontario Rail Map¶

The purpose of this notebook is to visualize the Ontario Railway Network. All data is taken from Ontario GeoHub.

Data Import¶

In [1]:
import os
import geopandas as gpd

cwd = os.getcwd()
tracks = gpd.read_file(cwd + "/Data/ORWNTRK/LIO-2022-10-19/ORWN_Track.shp")
marker_posts = gpd.read_file(cwd + "/Data/ORWNMKPO/LIO-2022-10-19/ORWN_MARKER_POST.shp")

Map¶

The map shows each subdivision in a different colour. Hovering over the subdivisions will show their name and operator.

CN, CP, and Metrolinx are shown by default, and subdivisions owned by other operators can be viewed by selecting them from the layer control at the top right of the map.

The map style can also be changed from the layer control. For the satellite view, turning on the Road Labels overlay will show the names of all the roads. This can be turned off when using another map style. An overlay for OpenRailwayMap is also available for reference.

In [2]:
import folium
import distinctipy
import random

# Define map and style choices
# See http://leaflet-extras.github.io/leaflet-providers/preview/ for options
m = folium.Map(location=[43.67621,-79.40530], zoom_start=6, tiles=None)

folium.TileLayer(tiles = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
                 attr = 'Esri', name = 'Esri Satellite', show=True).add_to(m)
folium.TileLayer(tiles='openstreetmap', name='Open Street Map').add_to(m)
folium.TileLayer(tiles='CartoDB dark_matter', name='CartoDB Dark Matter').add_to(m)
folium.TileLayer(tiles='CartoDB positron', name='CartoDB Positron').add_to(m)
folium.TileLayer(tiles='https://{s}.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png', 
                 attr='Open Railway Map', name='Open Railway Map', overlay=True, show=False).add_to(m)
folium.TileLayer(tiles='https://stamen-tiles-{s}.a.ssl.fastly.net/toner-hybrid/{z}/{x}/{y}.png', 
                 attr='Stamen Design', name='Road Labels', overlay=True, show=True).add_to(m)

# Tracks Data

# Generate a list of unique colours (as hex codes) to use for colouring all the subdivisions
# Fix the random seed so results don't change between runs
random.seed(15)
subs = tracks['SUBDI1NAME'].unique()
subs_dict = {k: v for v, k in enumerate(subs)}
sub_colors = distinctipy.get_colors(len(tracks['SUBDI1NAME'].unique()))
sub_colors = ['#%02x%02x%02x' % (int(255*c[0]), int(255*c[1]), int(255*c[2])) for c in sub_colors]

# Create a feature group for each operator
# Hide all the operators by default except for those in default_layers
default_layers = ['Canadian National', 'GO Transit – Metrolinx', 'Canadian Pacific']
features = {}
for row in tracks['OPERATOENA'].unique():
    features[row] = folium.FeatureGroup(name=row, show=True if row in default_layers else False)

for index, row in tracks.iterrows():
    # Define GeoJson for track segment
    geo_j = gpd.GeoSeries(row['geometry']).to_json()
    color = sub_colors[subs_dict[row['SUBDI1NAME']]]
    geo_j = folium.GeoJson(data=geo_j, name=row['SUBDI1NAME'], style_function=lambda x, color=color : {'color':color})
    
    label = "Subdivision: " + row['SUBDI1NAME'] + \
    "<br>" + "Operator: " + row['OPERATOENA'] + \
    "<br>" + "Track Class: " + str(row['TRACKCLASS'])
    
    folium.Tooltip(label).add_to(geo_j)
    
    # Add track segment to the feature group for its operator
    geo_j.add_to(features[row['OPERATOENA']])
    
# Add feature groups to the map    
for row in tracks['OPERATOENA'].unique():
    features[row].add_to(m)
    
# Marker Posts Data
# To-do: add to map


# Add layer Control to the map
folium.LayerControl().add_to(m)

# Show the map
m
Out[2]:
Make this Notebook Trusted to load map: File -> Trust Notebook
In [3]:
marker_posts.head()
Out[3]:
OGF_ID NID TRACKNID TRACKNAME TRACKCLASS SUBDI1NID SUBDI1NAME SUBD1DIST SUB1UNITDI SUB1DISTY ... GEOREVDATE GEOACQTECH GEOACCURA GEOPROVIDE ATTCREDATE ATTREVDATE ATTACQTECH ATTPROVIDE EFF_DATE geometry
0 83636 4097aa8fb73849da80c9baed941d4f64 829207c5405848ff9961f27c2fa7fb82 None Main dfe32e052a0d4ba8a5fd80df2d31afcf Bala 140.0 Mile Unknown ... 2016 Computed -1 Private 201306 2016 Vector Data Private 20170518131155 POINT (-79.88931 45.29124)
1 83637 f816e4631c754b9bbc6f1b93da6826c6 75dc72587a9847ebb2de50e53fef5f84 None Main dfe32e052a0d4ba8a5fd80df2d31afcf Bala 111.0 Mile Unknown ... 2016 Computed -1 Private 201306 2016 Vector Data Private 20170518131155 POINT (-79.57105 44.98406)
2 83638 55f643d5067d40f58074dc6dff95605d 0007b122f48f42c793bdc9c9c3222bcd None Main dfe32e052a0d4ba8a5fd80df2d31afcf Bala 29.0 Mile Unknown ... 2016 Computed -1 Private 201306 2016 Vector Data Private 20170518131155 POINT (-79.39699 43.97928)
3 83639 5656596e508b40c28b2b58013ce91534 faabf07328c9481482e9e7fe6ecb402d None Main dfe32e052a0d4ba8a5fd80df2d31afcf Bala 222.0 Mile Unknown ... 2016 Computed -1 Private 2016 2016 Vector Data Private 20170518131155 POINT (-80.75399 46.08861)
4 83640 6d244adc7ac0440b926f7e6614370a4f 23083e32043c40f2bc6fd8ed532eeee5 None Main dfe32e052a0d4ba8a5fd80df2d31afcf Bala 202.0 Mile Unknown ... 2016 Computed -1 Private 201306 2016 Vector Data Private 20170518131155 POINT (-80.52418 45.88345)

5 rows × 29 columns